"""
数据验证工具
"""

import re
from typing import Dict, Any, List, Optional
from app.core.exceptions import ValidationError


def validate_requirement(requirement: str) -> str:
    """
    验证需求描述
    
    Args:
        requirement: 需求描述文本
        
    Returns:
        清理后的需求描述
        
    Raises:
        ValidationError: 验证失败时抛出
    """
    if not requirement:
        raise ValidationError("需求描述不能为空", "requirement")
    
    # 清理文本
    cleaned = requirement.strip()
    
    if len(cleaned) < 10:
        raise ValidationError("需求描述至少需要10个字符", "requirement")
    
    if len(cleaned) > 10000:
        raise ValidationError("需求描述不能超过10000个字符", "requirement")
    
    # 检查是否包含有意义的内容（不只是空格和标点）
    meaningful_chars = re.sub(r'[\s\n\r\t\.,;:!?，。；：！？]', '', cleaned)
    if len(meaningful_chars) < 5:
        raise ValidationError("需求描述需要包含更多有意义的内容", "requirement")
    
    return cleaned


def validate_test_case(test_case: Dict[str, Any]) -> Dict[str, Any]:
    """
    验证测试用例数据
    
    Args:
        test_case: 测试用例字典
        
    Returns:
        验证后的测试用例数据
        
    Raises:
        ValidationError: 验证失败时抛出
    """
    if not isinstance(test_case, dict):
        raise ValidationError("测试用例必须是字典格式", "test_case")
    
    # 验证必需字段
    required_fields = ["title", "steps"]
    for field in required_fields:
        if field not in test_case or not test_case[field]:
            raise ValidationError(f"测试用例缺少必需字段: {field}", field)
    
    # 验证标题
    title = test_case.get("title", "").strip()
    if len(title) < 3:
        raise ValidationError("测试用例标题至少需要3个字符", "title")
    if len(title) > 200:
        raise ValidationError("测试用例标题不能超过200个字符", "title")
    
    # 验证步骤
    steps = test_case.get("steps", [])
    if not isinstance(steps, list):
        raise ValidationError("测试步骤必须是列表格式", "steps")
    if len(steps) == 0:
        raise ValidationError("测试用例至少需要一个步骤", "steps")
    if len(steps) > 20:
        raise ValidationError("测试用例步骤不能超过20个", "steps")
    
    # 验证每个步骤
    for i, step in enumerate(steps):
        if not isinstance(step, dict):
            raise ValidationError(f"第{i+1}个步骤必须是字典格式", f"steps[{i}]")
        
        if "description" not in step or not step["description"]:
            raise ValidationError(f"第{i+1}个步骤缺少描述", f"steps[{i}].description")
        
        if len(step["description"].strip()) < 3:
            raise ValidationError(f"第{i+1}个步骤描述至少需要3个字符", f"steps[{i}].description")
    
    # 验证优先级
    priority = test_case.get("priority", "P3")
    if priority not in ["P1", "P2", "P3", "P4"]:
        raise ValidationError("优先级必须是P1、P2、P3或P4", "priority")
    
    return test_case


def validate_project_name(project_name: str) -> str:
    """
    验证项目名称
    
    Args:
        project_name: 项目名称
        
    Returns:
        清理后的项目名称
        
    Raises:
        ValidationError: 验证失败时抛出
    """
    if not project_name:
        return ""
    
    cleaned = project_name.strip()
    
    if len(cleaned) > 100:
        raise ValidationError("项目名称不能超过100个字符", "project_name")
    
    # 检查是否包含非法字符
    if re.search(r'[<>:"/\\|?*]', cleaned):
        raise ValidationError("项目名称包含非法字符", "project_name")
    
    return cleaned


def validate_module_name(module_name: str) -> str:
    """
    验证模块名称
    
    Args:
        module_name: 模块名称
        
    Returns:
        清理后的模块名称
        
    Raises:
        ValidationError: 验证失败时抛出
    """
    if not module_name:
        return ""
    
    cleaned = module_name.strip()
    
    if len(cleaned) > 100:
        raise ValidationError("模块名称不能超过100个字符", "module_name")
    
    # 检查是否包含非法字符
    if re.search(r'[<>:"/\\|?*]', cleaned):
        raise ValidationError("模块名称包含非法字符", "module_name")
    
    return cleaned


def validate_test_types(test_types: List[str]) -> List[str]:
    """
    验证测试类型列表
    
    Args:
        test_types: 测试类型列表
        
    Returns:
        验证后的测试类型列表
        
    Raises:
        ValidationError: 验证失败时抛出
    """
    if not test_types:
        return ["functional"]
    
    if not isinstance(test_types, list):
        raise ValidationError("测试类型必须是列表格式", "test_types")
    
    valid_types = ["functional", "performance", "security", "usability", "compatibility"]
    
    validated_types = []
    for test_type in test_types:
        if not isinstance(test_type, str):
            continue
        
        cleaned_type = test_type.strip().lower()
        if cleaned_type in valid_types:
            validated_types.append(cleaned_type)
    
    if not validated_types:
        return ["functional"]
    
    return validated_types


def validate_email(email: str) -> str:
    """
    验证邮箱地址
    
    Args:
        email: 邮箱地址
        
    Returns:
        清理后的邮箱地址
        
    Raises:
        ValidationError: 验证失败时抛出
    """
    if not email:
        raise ValidationError("邮箱地址不能为空", "email")
    
    cleaned = email.strip().lower()
    
    # 简单的邮箱格式验证
    email_pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
    if not re.match(email_pattern, cleaned):
        raise ValidationError("邮箱地址格式不正确", "email")
    
    return cleaned
